class Observer {
  constructor(data) {
    this.walk(data);
  }

  walk(data) {
    // 判断data是否是空值或者不是对象
    if (!data || typeof data !== 'object') return;
    // 遍历data对象的所有属性
    Object.keys(data).forEach(key => {
      this.defineReactive(data, key, data[key]);
    })
  }

  defineReactive(data, key, val) {
    // 如果val是对象 把这个对象里的数据也转换成响应式数据
    this.walk(val);
    const self = this;
    // 创建DEP对象 负责收集依赖 并发送通知
    let dep = new Dep();
    Object.defineProperty(data, key, {
      enumerable: true,
      configurable: true,
      get() {
        // 收集依赖
        // 如果Dep有一个静态属性 target 那么 target 就是一个观察者 把他加入到 subs 中
        // 每 new 一个 watcher 会触发一次 addSub 因为只有在new watcher的时候 会存在target=new 的watcher 的实例
        Dep.target && dep.addSub(Dep.target);
        return val;
      },
      set(newVal) {
        if (newVal === val) return;
        val = newVal;
        self.walk(newVal);
        // 发送通知
        dep.notify();
      }
    });
    data.deps = data.deps || [];
    // dep会以闭包的形式存在 每个属性都有一个单独的dep
    // 例如页面中用到了5次 {{msg}} 那么 管理msg的dep中的subs里就会有5个watcher
    // 一旦msg更新 那么会触发这5个watcher里的update
    data.deps.push(dep);
  }
}